/** @file TextSurface.cpp */

#include "TextSurface.h"
#include "FileTools.h"

std::map<std::string, TextSurface::FontData> TextSurface::fonts;
std::string TextSurface::default_font_id;

void TextSurface::initialize()
{
	TTF_Init();

	//load the list of available fonts
	static const std::string file_name = "text/fonts.dat";

	lua_State* l = luaL_newstate();
	size_t size;
	char* buffer;
	FileTools::data_file_open_buffer(file_name, &buffer, &size);
    luaL_loadbuffer(l, buffer, size, file_name.c_str());
    FileTools::data_file_close_buffer(buffer);

	lua_register(l, "font", l_font);
	if(lua_pcall(l, 0, 0, 0) != 0)
	{
		std::cerr << "Error: Failed to load the fonts file\n";
		lua_pop(l, 1);
	}

	lua_close(l);
}

int TextSurface::l_font(lua_State* l)
{
	luaL_checktype(l, 1, LUA_TTABLE);

	const std::string& font_id = LuaContext::check_string_field(l, 1, "id");
	const std::string& file_name = LuaContext::check_string_field(l, 1, "file");
	int font_size = LuaContext::opt_int_field(l, 1, "size", 11);
	bool is_default = LuaContext::opt_boolean_field(l, 1, "default", false);

	fonts[font_id].file_name = file_name;
	fonts[font_id].font_size = font_size;

	if(is_default || default_font_id.empty())
	{
		default_font_id = font_id;
	}

	//load the font
	size_t index = file_name.rfind('.');
	std::string extension;
	if(index != std::string::npos)
	{
		extension = file_name.substr(index);
	}

	if(extension == ".png" || extension == ".PNG")
	{
		//It's a bitmap font
		fonts[font_id].bitmap = new Surface(file_name, Surface::DIR_DATA);
	}
	else
	{
		//It's a normal font
		size_t size;
		FileTools::data_file_open_buffer(file_name, &fonts[font_id].buffer, &size);
		fonts[font_id].bitmap = NULL;
		fonts[font_id].rw = SDL_RWFromMem(fonts[font_id].buffer, int(size));
		fonts[font_id].internal_font = TTF_OpenFontRW(fonts[font_id].rw, 0, font_size);
		/*Debug::check_assertion(fonts[font_id].internal_font != NULL,
			StringConcat() << "Cannot load font from file '" << file_name << "': " << TTF_GetError());*/
	}
	return 0;
}

/**
* \brief Sets the string drawn.
*
* If the specified string is the same than the current text, nothing is done.
*
* \param text the text to display (cannot be NULL)
*/
void TextSurface::set_text(const std::string& text)
{
	if(text != this->text)
	{
		//There is a change
		this->text = text;
		rebuild();
	}
}

/**
* \brief Redraws the text surface.
*
* This function is called when there is a change.
*/
void TextSurface::rebuild()
{
	
}